package com.jsh.erp;

import com.jsh.erp.constants.BusinessConstants;
import com.jsh.erp.datasource.entities.*;
import com.jsh.erp.datasource.mappers.DepotHeadMapper;
import com.jsh.erp.datasource.mappers.MaterialExtendMapper;
import com.jsh.erp.service.DepotItemService;
import com.jsh.erp.service.SequenceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
@Component
public class OrderJob implements ApplicationListener<ApplicationReadyEvent> {

    private List<MaterialExtend> materialExtends;
    private BigDecimal outSumPriceTotal = BigDecimal.ZERO;
    private BigDecimal maxPrice = BigDecimal.ZERO;

    @Resource
    private MaterialExtendMapper materialExtendMapper;
    @Resource
    private DepotHeadMapper depotHeadMapper;
    @Resource
    private DepotItemService depotItemService;
    @Resource
    private SequenceService sequenceService;


    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        log.info("order job start");
        MaterialExtendExample example = new MaterialExtendExample();
        example.createCriteria();
        materialExtends = materialExtendMapper.selectByExample(example);

        DateTimeFormatter d = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        int[][] dests = {
//                {2024, 8, 31051752},
//                {2024, 9, 34252515},
//                {2024, 10, 38151395},
//                {2024, 11, 39014751},
//                {2024, 12, 39195505},
//                {2025, 1, 52994216},
//                {2025, 2, 52018157},
//                {2025, 3, 52698386},
//                {2025, 4, 50035007},
//                {2025, 5, 50128761},
//                {2025, 6, 2341364},
//                {2025, 7, 27561057},
        };
        for (int[] dest : dests) {
            LocalDate destMonth = LocalDate.of(dest[0], dest[1], 1);
            try {
                String[] organArray = {"90"};
                String beginTime = d.format(destMonth) + " 00:00:00";
                String endTime = d.format(destMonth.plusMonths(1).minusDays(1)) + " 23:59:59";
                maxPrice = new BigDecimal(dest[2]);
                //总销售额
                outSumPriceTotal = depotItemService.buyOrSalePriceTotal("出库", "销售", null,
                        beginTime, endTime, null, null, organArray, new ArrayList<>(), new ArrayList<>(), false);

                boolean full = false;

                while (!full) {
                    Map<MaterialExtend, Integer> list = randomList();
                    Date date = randomDate(destMonth);
                    full = createSale(list, date);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    Date randomDate(LocalDate destMonth) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, destMonth.getYear());
        calendar.set(Calendar.MONTH, destMonth.getMonthValue() - 1);
        calendar.set(Calendar.DATE, RandomUtils.nextInt(1, destMonth.lengthOfMonth() + 1));
        calendar.set(Calendar.HOUR_OF_DAY, RandomUtils.nextInt(8, 22));
        calendar.set(Calendar.MINUTE, RandomUtils.nextInt(0, 60));
        calendar.set(Calendar.SECOND, RandomUtils.nextInt(0, 60));
        return calendar.getTime();
    }

    @SuppressWarnings("deprecation")
    private Map<MaterialExtend, Integer> randomList() {
        int count = RandomUtils.nextInt(1, 6);// 商品种类
        Map<MaterialExtend, Integer> list = new HashMap<>();

        for (int i = 0; i < count; i++) {
            MaterialExtend extend = materialExtends.get(RandomUtils.nextInt(0, materialExtends.size()));
            list.put(extend, RandomUtils.nextInt(1, 11));// 商品数量
        }

        return list;
    }

    String buildOnlyNumber(String prefix, Date date) throws Exception {
        String no = sequenceService.buildOnlyNumber();
        String yyyyMMdd = DateFormatUtils.format(date, "yyyyMMdd");
        return prefix + yyyyMMdd + no.substring(8);
    }

    /**
     * 生成订单
     *
     * @return
     */

    private boolean createSale(Map<MaterialExtend, Integer> exList, Date date) throws Exception {
        List<DepotItem> items = new ArrayList<>();
        BigDecimal totalPrice = createSaleItem(exList, items);
        outSumPriceTotal = outSumPriceTotal.add(totalPrice);

        if (maxPrice.compareTo(outSumPriceTotal) < 0) {
            return true;
        }

        DepotHead depotHead = new DepotHead();
        depotHead.setType("其它");
        depotHead.setSubType(BusinessConstants.SUB_TYPE_SALES_ORDER);
        depotHead.setDefaultNumber(buildOnlyNumber("XSDD", date));
        depotHead.setNumber(depotHead.getDefaultNumber());
        depotHead.setCreateTime(date);
        depotHead.setOperTime(date);
        depotHead.setOrganId(90L);
        depotHead.setCreator(120L);
        depotHead.setAccountId(17L);
        depotHead.setChangeAmount(BigDecimal.ZERO);
        depotHead.setTotalPrice(totalPrice);
        depotHead.setPayType("现付");
        depotHead.setFileName("");
        depotHead.setSalesMan("");
        depotHead.setAccountIdList("");
        depotHead.setAccountMoneyList("");
        depotHead.setDiscount(BigDecimal.ZERO);
        depotHead.setDiscountMoney(BigDecimal.ZERO);
        depotHead.setDiscountLastMoney(depotHead.getTotalPrice());
        depotHead.setStatus(BusinessConstants.BILLS_STATUS_SKIPED);
        depotHead.setPurchaseStatus(BusinessConstants.PURCHASE_STATUS_UN_AUDIT);
        depotHead.setSource("0");
//        depotHead.setTenantId(63L);
        depotHead.setDeleteFlag("0");
        depotHeadMapper.insertSelective(depotHead);

        //根据单据编号查询单据id
        DepotHeadExample dhExample = new DepotHeadExample();
        dhExample.createCriteria().andNumberEqualTo(depotHead.getNumber()).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<DepotHead> list = depotHeadMapper.selectByExample(dhExample);
        depotHead.setId(list.get(0).getId());

        for (DepotItem item : items) {
            item.setHeaderId(depotHead.getId());
            depotItemService.insertDepotItemWithObj(item);
        }


        createOut(depotHead);
        return false;
    }

    BigDecimal createSaleItem(Map<MaterialExtend, Integer> exList, List<DepotItem> items) {
        BigDecimal totalMoney = BigDecimal.ZERO;
        DepotItem depotItem;

        for (Map.Entry<MaterialExtend, Integer> entry : exList.entrySet()) {
            depotItem = new DepotItem();
            MaterialExtend ex = entry.getKey();
            BigDecimal count = new BigDecimal(entry.getValue());

            depotItem.setMaterialId(ex.getMaterialId());
            depotItem.setMaterialExtendId(ex.getId());
            depotItem.setMaterialUnit("桶");
            depotItem.setOperNumber(count);
            depotItem.setBasicNumber(count);
            depotItem.setUnitPrice(ex.getWholesaleDecimal());
            depotItem.setAllPrice(depotItem.getOperNumber().multiply(depotItem.getUnitPrice()));
            depotItem.setTaxRate(BigDecimal.ZERO);
            depotItem.setTaxMoney(BigDecimal.ZERO);
            depotItem.setTaxLastMoney(depotItem.getAllPrice());
//            depotItem.setTenantId(63L);
            depotItem.setDeleteFlag("0");
            items.add(depotItem);

            totalMoney = totalMoney.add(depotItem.getAllPrice());
        }

        return totalMoney;
    }

    /**
     * 生成出库
     */

    private void createOut(DepotHead order) throws Exception {
        Date date = new Date(order.getCreateTime().getTime() + RandomUtils.nextInt(60 * 1000, 20 * 60 * 1000));// 出库延后1-20分钟

        DepotHead depotHead = new DepotHead();
        depotHead.setType("出库");
        depotHead.setSubType(BusinessConstants.SUB_TYPE_SALES);
        depotHead.setDefaultNumber(buildOnlyNumber("XSCK", date));
        depotHead.setNumber(depotHead.getDefaultNumber());
        depotHead.setCreateTime(date);
        depotHead.setOperTime(date);
        depotHead.setOrganId(90L);
        depotHead.setCreator(120L);
        depotHead.setAccountId(17L);
        depotHead.setChangeAmount(order.getTotalPrice());
        depotHead.setTotalPrice(order.getTotalPrice());
        depotHead.setPayType("现付");
        depotHead.setFileName("");
        depotHead.setSalesMan("");
        depotHead.setAccountIdList("");
        depotHead.setAccountMoneyList("");
        depotHead.setDiscount(BigDecimal.ZERO);
        depotHead.setDiscountMoney(BigDecimal.ZERO);
        depotHead.setDiscountLastMoney(depotHead.getTotalPrice());
        depotHead.setOtherMoney(BigDecimal.ZERO);
        depotHead.setStatus(BusinessConstants.BILLS_STATUS_AUDIT);
        depotHead.setPurchaseStatus(BusinessConstants.PURCHASE_STATUS_UN_AUDIT);
        depotHead.setSource("0");
        depotHead.setLinkNumber(order.getNumber());
//        depotHead.setTenantId(63L);
        depotHead.setDeleteFlag("0");
        depotHeadMapper.insertSelective(depotHead);

        //根据单据编号查询单据id
        DepotHeadExample dhExample = new DepotHeadExample();
        dhExample.createCriteria().andNumberEqualTo(depotHead.getNumber()).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<DepotHead> list = depotHeadMapper.selectByExample(dhExample);
        depotHead.setId(list.get(0).getId());

        List<DepotItem> orderItems = depotItemService.getListByHeaderId(order.getId());

        for (DepotItem item : orderItems) {
            item.setHeaderId(depotHead.getId());
            item.setPurchaseUnitPrice(BigDecimal.ZERO);
            item.setDepotId(14L);
            item.setLinkId(item.getId());
            item.setId(null);
            item.setTenantId(null);

            depotItemService.insertDepotItemWithObj(item);
//            depotItemService.updateCurrentStock(item);
        }

    }
}
